﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccessLayer.Properties;
using System.Transactions;
using IMModel.Domain;

namespace DataAccessLayer.Admin.Copy.IndexMarkStruct
{
    public class CharacteristicCopyWithGradations : ICopy
    {
        private ICopy categoryCopy = new CategoryCopy();
        private Dictionary<int, int> dic_gradRel = new Dictionary<int, int>();

        public int Copy(int IDCopiedObject, int? IDParentObject, int fromIDTerm, int toIDTerm)
        {
            if (IDParentObject == null)
            {
                throw new ArgumentException("IDParentObject не может быть == NULL");
            }

            using (IMModel.Domain.IMDataDataContext db = new IMModel.Domain.IMDataDataContext(Settings.Default.IndexMarkConnectionString))
            {
                using (var transaction = new TransactionScope())
                {
                    SqlDataProvider sql = new SqlDataProvider();
                    CharacteristicTerm old = db.CharacteristicTerms.Single(s => s.IDCharacteristicTerm == IDCopiedObject);

                    int IDSectionTerm = (int)IDParentObject;
                    int IDCategoryTerm = this.categoryCopy.Copy(old.CategorySectionTerm.IDCategoryTerm, null, fromIDTerm, toIDTerm);
                    int IDCategorySectionTerm = sql.GetIDCategorySectionTerm(IDSectionTerm, IDCategoryTerm);

                    CharacteristicTerm _new = new CharacteristicTerm
                    {
                        IDCharacteristic = old.IDCharacteristic,
                        IDTerm = toIDTerm,
                        Weight = old.Weight,
                        Order = old.Order,
                        IDCategorySectionTerm = IDCategorySectionTerm,
                        IDUnit = old.IDUnit,
                        Visibility = old.Visibility,
                        IDPrevCharacteristicTerm = old.IDCharacteristicTerm,
                        IndexRequired = old.IndexRequired,
                        VolumeValidPeriod = old.VolumeValidPeriod
                    };
                    db.CharacteristicTerms.InsertOnSubmit(_new);

                    var responsibles = from ct in db.CharacteristicTerms
                                       join cr in db.CharacteristicResponsibles on ct.IDCharacteristicTerm equals cr.IDCharacteristicTerm
                                       where ct.IDCharacteristicTerm == old.IDCharacteristicTerm
                                       select cr;
                    foreach (var r in responsibles)
                    {
                        CharacteristicResponsible charResp = new CharacteristicResponsible
                        {
                            CharacteristicTerm = _new,
                            IDResponsible = r.IDResponsible
                        };
                        db.CharacteristicResponsibles.InsertOnSubmit(charResp);
                    }

                    foreach (CharacteristicGroup oldCharGroup in db.CharacteristicGroups.Where(
                        w => w.IDCharacteristicTerm == old.IDCharacteristicTerm))
                    {
                        if (dic_gradRel.Count == 0) dic_gradRel = this.CopyGradationRelations(fromIDTerm, toIDTerm);
                        CharacteristicGroup charGroup = new CharacteristicGroup
                        {
                            CharacteristicTerm = _new,
                            IDGradationGroupTerm = dic_gradRel[oldCharGroup.IDGradationGroupTerm]
                        };

                        db.CharacteristicGroups.InsertOnSubmit(charGroup);
                    }

                    db.SubmitChanges();

                    transaction.Complete();

                    return _new.IDCharacteristicTerm;
                }
            }
        }

        private Dictionary<int, int> CopyGradationRelations(int fromIDTerm, int toIDTerm)
        {
            using (IMModel.Domain.IMDataDataContext db = new IMModel.Domain.IMDataDataContext(Settings.Default.IndexMarkConnectionString))
            {
                using (var transaction = new TransactionScope())
                {
                    Dictionary<GradationTerm, GradationTerm> dic = new Dictionary<GradationTerm, GradationTerm>();
                    Dictionary<int, int> dic_keys = new Dictionary<int, int>();

                    foreach (GradationTerm gr in db.GradationTerms.Where(w => w.IDTerm == fromIDTerm))
                    {
                        GradationTerm new_gr = new GradationTerm
                        {
                            Weight = gr.Weight,
                            Order = gr.Order,
                            IDGradation = gr.IDGradation,
                            IDTerm = toIDTerm
                        };
                        dic.Add(gr, new_gr);
                    }
                    foreach (KeyValuePair<GradationTerm, GradationTerm> el in dic)
                    {
                        if (el.Key.GradationTerm1 != null)
                        {
                            el.Value.GradationTerm1 = dic[el.Key.GradationTerm1];
                        }
                    }
                    db.GradationTerms.InsertAllOnSubmit(dic.Values);
                    db.SubmitChanges();
                    foreach (KeyValuePair<GradationTerm, GradationTerm> el in dic)
                    {
                        dic_keys.Add(el.Key.IDGradationTerm, el.Value.IDGradationTerm);
                    }

                    // Фиксируем транзакцию
                    transaction.Complete();

                    return dic_keys;
                }
            }
        }
    }
}
